home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / 123_01.zip / TR.C < prev    next >
Text File  |  1993-06-07  |  6KB  |  319 lines

  1. /*
  2.     Transliteration filter
  3.     Adapted from Software Tools, by Kernighan & Plauger.
  4.  
  5.     source:  tr.c
  6.     version: February 22, 1983
  7.  
  8.     Link this program to the directed I/O packages as follows:
  9.     A>clink tr -f dio
  10.  
  11.     Transliterated from RATFOR to BDS C by:
  12.  
  13.         Robert Pasky
  14.         36 Wiswall Rd
  15.         Newton, MA 02159
  16.         (617) 964-3641
  17.  
  18.     Edited by:
  19.  
  20.         Edward K. Ream
  21.         1850 Summit Ave.
  22.         Madison, WI 53705
  23.         (608) 231 - 2952
  24.  
  25.  
  26.     See the file tr.doc for complete documentation.
  27. */
  28.  
  29.  
  30. #include "bdscio.h"
  31. #include "dio.h"
  32.  
  33. #define MAXSET 129
  34. #define NOTSYM '~'
  35. #define ESCAPE '\\'
  36. #define DASH '-'
  37. #define UPPER 1
  38. #define LOWER 0
  39. #define YES 1
  40. #define NO 2
  41.  
  42. /* comment out ----- remove this comment to get debugging messages
  43. #define DEBUG 1
  44. ----- end comment out */
  45.  
  46. int casesw;
  47. int ix, jx;
  48.  
  49. main(argc, argv)
  50. int  argc;
  51. char **argv;
  52. {
  53.     /* Set up the filter. */
  54.     _allocp = NULL;
  55.     dioinit(&argc, argv);
  56.     main1(argc, argv);
  57.  
  58.     /* Indicate no error in the pipe. */
  59.     dioflush();    
  60. }
  61.  
  62.  
  63. /* Main line. */
  64.  
  65. main1(argc, argv)
  66. int argc;
  67. char *argv[];
  68. {
  69.     int  c;
  70.     char from[MAXSET], to[MAXSET];
  71.     char *s;
  72.     int allbut, collap, i, lastto;
  73.  
  74.     if (argc < 2) {
  75.         fprintf(STD_ERR,
  76.         "usage: tr <infile [>outfile] from [to]\n");
  77.         dioflush();
  78.         exit();
  79.     }
  80.  
  81.     casesw = LOWER;
  82.     s = *++argv;
  83.  
  84.     from[0] = NULL;
  85.     if (s[0] == NOTSYM) {
  86.         allbut = YES;
  87.         if (makset(s, 1, from) == NO) {
  88.             fprintf(STD_ERR, "<from> too large\n");
  89.             dioflush();
  90.             exit();
  91.         }
  92.     }
  93.     else {
  94.         allbut = NO;
  95.         if (makset(s, 0, from) == NO) {
  96.             fprintf(STD_ERR, "<from> too large\n");
  97.             dioflush();
  98.             exit();
  99.         }
  100.     }
  101.  
  102. #ifdef DEBUG
  103.     fprintf(STD_ERR, "from: <%s>\n", from);
  104. #endif
  105.  
  106.     casesw = LOWER;
  107.     s = *++argv;
  108.  
  109.     to[0] = NULL;
  110.     if (argc <= 2 || s[0] == NULL) {
  111.         to[0] = NULL;
  112.     }
  113.     else if (makset(s, 0, to) == NO) {
  114.         fprintf(STD_ERR, "<to> too large\n");
  115.         dioflush();
  116.         exit();    
  117.     }
  118.  
  119. #ifdef DEBUG
  120.     fprintf(STD_ERR, "to: <%s>\n", to);
  121. #endif
  122.  
  123.     lastto = strlen(to) - 1;
  124.     if (strlen(from) > (lastto + 1) || allbut == YES) {
  125.         collap = YES;
  126.     }
  127.     else {
  128.         collap = NO;
  129.     }
  130.  
  131.     for(;;) {
  132.         c = getchar();
  133.         i = xindex(from, c, allbut, lastto);
  134.         if (collap == YES && i >= lastto && lastto >= 0) {
  135.             putchar(to[lastto]);
  136.             do {
  137.                 c = getchar();
  138.                 i = xindex(from, c, allbut, lastto);
  139.             } while (i >= lastto);
  140.         }
  141.         if (c == CPMEOF || c == EOF) {
  142.             break;
  143.         }
  144.         if (i >= 0 && lastto >= 0) {
  145.             putchar(to[i]);
  146.         }
  147.         else if (i == -1) {
  148.             putchar(c);
  149.         }
  150.     }
  151. }
  152.  
  153.  
  154. makset(array, k, set)    /* make the from/to set from array */
  155. int k;
  156. char array[], set[];
  157. {
  158.     ix = k;
  159.     jx = 0;
  160.     filset(NULL, array, set);
  161.     return (addset(NULL, set));
  162. }
  163.  
  164.  
  165. addset(c, set)        /* add single code to set */
  166. char c, set[];
  167. {
  168.     if (jx > MAXSET)
  169.         return(NO);
  170.     set[jx++] = c;
  171.     return (YES);
  172.  
  173. }
  174.  
  175.  
  176. filset(delim, array, set)    /* fill set from array */
  177. char delim, array[], set[];
  178. {
  179.     char digits[11];
  180.     char lowalf[27];
  181.     char upalf[27];
  182.     char c;
  183.  
  184.     strcpy(digits, "0123456789");
  185.     strcpy(lowalf, "abcdefghijlkmnopqrstuvwxyz");
  186.     strcpy(upalf, "ABCDEFGHIJLKMNOPQRSTUVWXYZ");
  187.  
  188.     for ( ; array[ix] != delim && array[ix] != NULL; ix++) {
  189.         if (array[ix] == ESCAPE) {
  190.             if ((c = esc(array)) != NULL) {
  191.                 addset(c, set);
  192.             }
  193.         }
  194.         else if (array[ix] != DASH) {
  195.             if (casesw == LOWER) {
  196.                 array[ix] = tolower(array[ix]);
  197.             }
  198.             addset(array[ix], set);
  199.         }
  200.         else if (jx <= 0 || array[ix + 1] == NULL) {
  201.             addset(DASH, set);
  202.         }
  203.         else if (index(digits, set[jx - 1]) >= 0 ) {
  204.             dodash(digits, array, set);
  205.         }
  206.         else if (index(lowalf, set[jx - 1]) >= 0 ) {
  207.             dodash(lowalf, array, set);
  208.         }
  209.         else if (index(upalf, set[jx - 1]) >= 0 ) {
  210.             dodash(upalf, array, set);
  211.         }
  212.         else {
  213.             addset(DASH, set);
  214.         }
  215.     }
  216. }
  217.  
  218.  
  219. dodash(valid, array, set)    /* parse intervals */
  220. char valid[], array[], set[];
  221. {
  222.     int k, limit;
  223.     ix++;
  224.     jx--;
  225.  
  226.     limit = index(valid, esc(array));
  227.     for (k = index(valid, set[jx]); k <= limit; k++) {
  228.         addset(valid[k], set);
  229.     }
  230. }
  231.  
  232.  
  233. esc(array)        /* handle escape sequences, returns intended code */
  234. char array[];
  235. {
  236.     int sum;
  237.  
  238.     if (casesw == LOWER) {
  239.         array[ix] = tolower(array[ix]);
  240.     }
  241.     if (array[ix] != ESCAPE) {
  242.         return (array[ix]);
  243.     }
  244.     else if (array[ix + 1] == NULL) {
  245.         return (ESCAPE);
  246.     }
  247.     else {
  248.         ix++;
  249.         switch(tolower(array[ix])) {
  250.         case 'n':
  251.             return('\n');
  252.         case 't':
  253.             return('\t');
  254.         case 'b':
  255.             return(' ');
  256.         case 'r':
  257.             return('\r');
  258.         case 'l':
  259.             casesw = LOWER;
  260.             return (NULL);
  261.         case 'u':
  262.             casesw = UPPER;
  263.             return (NULL);
  264.         case '0':    case '1':
  265.         case '2':    case '3':
  266.         case '4':    case '5':
  267.         case '6':    case '7':
  268.             sum = array[ix] - '0';
  269.             while (isdigit(array[ix+1])) {
  270.                 sum = sum * 8 + array[ix++] - '0';
  271.             }
  272.             return (sum & 0xff);
  273.  
  274.         default:
  275.             if (casesw == LOWER) {
  276.                 array[ix] = tolower(array[ix]);
  277.             }
  278.             return(array[ix]); /* takes care of ESCAPE ESCAPE */
  279.         }
  280.     }
  281. }
  282.  
  283.  
  284. xindex(array, c, allbut, lastto)    /* return index of c
  285.                        modified by allbut */
  286. char array[], c;
  287. int allbut, lastto;
  288. {
  289.     int i;
  290.  
  291.     if (c == NULL) {
  292.         return (-1);
  293.     }
  294.     else if (allbut == NO) {
  295.         return (index(array, c));
  296.     }
  297.     else if (index(array, c) >= 0) {
  298.         return (-1);
  299.     }
  300.     else {
  301.         return (lastto + 1);
  302.     }
  303. }
  304.  
  305.  
  306. index(s, c)        /* return index of c in s */
  307. char *s, c;
  308. {
  309.     int i;
  310.  
  311.     for (i = 0; s[i] != NULL; i++) {
  312.         if(s[i] == c) {
  313.             return (i);
  314.         }
  315.     }
  316.     return (-1);
  317. }
  318. /
  319. char *s,